﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.HVAC;
using YArchitech.Revit;

namespace YArchitech.Plumbing.ExtendElementSet
{
	public class ExtendElementsHelper
	{
		public ExtendElementsHelper(UIDocument uiDoc)
		{
			this.doc = uiDoc.Document;
			this.sel = uiDoc.Selection;
		}

		public List<Element> IntersectElemList
		{
			get
			{
				return this.intersectElemList;
			}
			set
			{
				this.intersectElemList = value;
			}
		}

		public List<YJKLine> InterectElemsLine
		{
			get
			{
				return this.interectElemsLine;
			}
			set
			{
				this.interectElemsLine = value;
			}
		}

		public List<YJKLine> InsideElemsLine
		{
			get
			{
				return this.insideElemsLine;
			}
			set
			{
				this.insideElemsLine = value;
			}
		}

		public List<Element> InsideElemList
		{
			get
			{
				return this.insideElemList;
			}
			set
			{
				this.insideElemList = value;
			}
		}

		public List<FilledRegion> FilledRegions
		{
			get
			{
				return this.filledRegions;
			}
			set
			{
				this.filledRegions = value;
			}
		}

		public string OperateMsg
		{
			get
			{
				return this.operateMsg;
			}
		}

		public bool SelectAndGroupExtendingElements()
		{
			IList<Element> allElements = this.SelectingElementList(ref this.pickedBox);
			this.GroupSelectedElements(allElements, this.pickedBox);
			if ((this.IntersectElemList == null || this.IntersectElemList.Count < 1) && (this.InsideElemList == null || this.InsideElemList.Count < 1) && (this.groupList == null || this.groupList.Count < 1) && (this.FilledRegions == null || this.FilledRegions.Count < 1))
			{
				return false;
			}
			this.GetInsideElementsLineList();
			return true;
		}

		private void GetInsideElementsLineList()
		{
			this.GetInsideCuvreElementLineList();
			this.GetInsideFamilyInstanceBoxLineList();
		}

		private void GetInsideCuvreElementLineList()
		{
			if (this.insideCurveElems == null || this.insideCurveElems.Count < 1)
			{
				return;
			}
			foreach (Element element in this.insideCurveElems)
			{
				LocationCurve locationCurve = element.Location as LocationCurve;
				Curve curve = null;
				if (locationCurve == null)
				{
					if (element is Grid)
					{
						curve = (element as Grid).Curve;
					}
				}
				else
				{
					curve = locationCurve.Curve;
				}
				YJKLine item = new YJKLine(curve.GetEndPoint(0), curve.GetEndPoint(1));
				this.insideElemsLine.Add(item);
			}
		}

		private void GetInsideFamilyInstanceBoxLineList()
		{
			if (this.insideFamilyInstances == null || this.insideFamilyInstances.Count < 1)
			{
				return;
			}
			foreach (Element element in this.insideFamilyInstances)
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				if (familyInstance != null)
				{
					BoundingBoxXYZ familyInstanceBox = UnifiedModified.GetFamilyInstanceBox(familyInstance);
					this.AddBoundingBoxPoints(familyInstanceBox);
				}
			}
		}

		private void AddBoundingBoxPoints(BoundingBoxXYZ boundingBox)
		{
			XYZ xyz = YJKRevitTools.SetZToZero(boundingBox.Max);
			XYZ xyz2 = YJKRevitTools.SetZToZero(boundingBox.Min);
			Transform transform = boundingBox.Transform;
			YJKLine hyline = new YJKLine(xyz, xyz.Add(transform.BasisX));
			hyline.MakeUnBound();
			XYZ project = hyline.GetProject(xyz2);
			YJKLine item = new YJKLine(xyz, project);
			this.insideElemsLine.Add(item);
			item = new YJKLine(xyz2, project);
			this.insideElemsLine.Add(item);
			YJKLine hyline2 = new YJKLine(xyz, xyz.Add(transform.BasisY));
			hyline2.MakeUnBound();
			XYZ project2 = hyline2.GetProject(xyz2);
			item = new YJKLine(xyz, project2);
			this.insideElemsLine.Add(item);
			item = new YJKLine(xyz2, project2);
			this.insideElemsLine.Add(item);
		}

		private IList<Element> SelectingElementList(ref PickedBox pickedBox)
		{
			RevitVersionFuncs.ClearSelection(this.sel);
			pickedBox = this.sel.PickBox(0, "请选择移动或拉伸的实体集合……");
			double[] viewRange = this.GetViewRange(this.doc.ActiveView);
			if (viewRange == null)
			{
				this.operateMsg = "操作视图必须为平面视图！";
				return null;
			}
			Outline outline = this.CreatOutLine(viewRange, pickedBox.Max, pickedBox.Min);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline);
			IList<Element> list = new FilteredElementCollector(this.doc, this.doc.ActiveView.Id).WherePasses(boundingBoxIntersectsFilter).ToElements();
			foreach (Element element in new FilteredElementCollector(this.doc, this.doc.ActiveView.Id).OfClass(typeof(IndependentTag)).ToElements())
			{
				if (element is IndependentTag)
				{
					IndependentTag independentTag = element as IndependentTag;
					if (outline.Contains(independentTag.TagHeadPosition, 1E-07) && !list.Contains(element))
					{
						list.Add(element);
					}
				}
			}
			return list;
		}

		private void GetSelectGrids()
		{
			IList<Element> list = new FilteredElementCollector(this.doc, this.doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Grids).ToElements();
			if (list == null || list.Count < 1)
			{
				return;
			}
			foreach (Element element in list)
			{
				Grid grid = element as Grid;
				if (grid != null)
				{
					Curve curve = grid.Curve;
					int num = this.CheckPointInPickBox(this.pickedBox, curve);
					if (num == 1)
					{
						RevitVersionFuncs.AddToSelection(this.sel, element);
						this.insideCurveElems.Add(grid);
						this.insideElemList.Add(grid);
					}
					else if (num == 0)
					{
						RevitVersionFuncs.AddToSelection(this.sel, element);
						YJKLine item = new YJKLine(curve.GetEndPoint(0), curve.GetEndPoint(1));
						this.interectElemsLine.Add(item);
						this.intersectElemList.Add(grid);
					}
				}
			}
		}

		private int CheckPointInPickBox(PickedBox pickedBox, Curve curve)
		{
			XYZ max = pickedBox.Max;
			XYZ min = pickedBox.Min;
			double x = max.X;
			double x2 = min.X;
			double y = max.Y;
			double y2 = min.Y;
			this.JudgeX(ref x, ref x2);
			this.JudgeX(ref y, ref y2);
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			int result;
			if ((this.PointInSection(hyendPoint, x, x2, y, y2) && !this.PointInSection(hyendPoint2, x, x2, y, y2)) || (!this.PointInSection(hyendPoint, x, x2, y, y2) && this.PointInSection(hyendPoint2, x, x2, y, y2)))
			{
				result = 0;
			}
			else if (this.PointInSection(hyendPoint, x, x2, y, y2) && this.PointInSection(hyendPoint2, x, x2, y, y2))
			{
				result = 1;
			}
			else
			{
				result = -1;
			}
			return result;
		}

		private bool PointInSection(XYZ point, double maxX, double minX, double maxY, double minY)
		{
			bool result = false;
			if (this.BeInSection(point.X, minX, maxX) && this.BeInSection(point.Y, minY, maxY))
			{
				result = true;
			}
			return result;
		}

		private bool BeInSection(double baseValue, double sectionA, double sectionB)
		{
			return baseValue >= sectionA && baseValue <= sectionB;
		}

		private void JudgeX(ref double maxX, ref double minX)
		{
			double num = maxX;
			double num2 = minX;
			if (maxX < minX)
			{
				num = minX;
				num2 = maxX;
			}
			maxX = num;
			minX = num2;
		}

		private void GroupSelectedElements(IList<Element> allElements, PickedBox pickedBox)
		{
			this.boundingBoxPoints = this.GetPickedBoundingBox(pickedBox);
			YJKLine item = null;
			this.GetSelectGrids();
			foreach (Element element in allElements)
			{
				if (element.Category.Id.IntegerValue != -2000500)
				{
					RevitVersionFuncs.AddToSelection(this.sel, element);
					if (element is Group)
					{
						Group item2 = element as Group;
						this.groupList.Add(item2);
					}
					else if (element is FilledRegion)
					{
						FilledRegion item3 = element as FilledRegion;
						this.filledRegions.Add(item3);
					}
					else
					{
						Location location = element.Location;
						if (location is LocationCurve || element is Grid)
						{
							if (!(element is Grid))
							{
								Curve curve = (location as LocationCurve).Curve;
								switch (this.CheckCurveInSideBox(curve, ref item))
								{
								case -1:
									this.insideElemList.Add(element);
									break;
								case 0:
									this.interectElemsLine.Add(item);
									this.intersectElemList.Add(element);
									break;
								case 1:
									this.insideCurveElems.Add(element);
									this.insideElemList.Add(element);
									break;
								}
							}
						}
						else if (location is LocationPoint)
						{
							this.insideFamilyInstances.Add(element);
							this.insideElemList.Add(element);
						}
						else
						{
							this.insideElemList.Add(element);
						}
					}
				}
			}
		}

		private int CheckCurveInSideBox(Curve curve, ref YJKLine hyLine)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = YJKRevitTools.SetZToZero(hyendPoint);
			XYZ xyz2 = YJKRevitTools.SetZToZero(hyendPoint2);
			bool flag = YJKRevitTools.Contains(xyz, this.boundingBoxPoints);
			bool flag2 = YJKRevitTools.Contains(xyz2, this.boundingBoxPoints);
			int result;
			if (!flag && !flag2)
			{
				result = -1;
			}
			else if (flag && !flag2)
			{
				result = 0;
				hyLine = new YJKLine(xyz2, xyz);
			}
			else if (!flag && flag2)
			{
				result = 0;
				hyLine = new YJKLine(xyz, xyz2);
			}
			else
			{
				result = 1;
			}
			return result;
		}

		private List<XYZ> GetPickedBoundingBox(PickedBox pickedBox)
		{
			List<XYZ> list = new List<XYZ>();
			double x = pickedBox.Max.X;
			double y = pickedBox.Max.Y;
			double x2 = pickedBox.Min.X;
			double y2 = pickedBox.Min.Y;
			list.Add(new XYZ(x, y, 0.0));
			list.Add(new XYZ(x, y2, 0.0));
			list.Add(new XYZ(x2, y2, 0.0));
			list.Add(new XYZ(x2, y, 0.0));
			return list;
		}

		private double[] GetViewRange(View view)
		{
			if (!(view is ViewPlan))
			{
				return null;
			}
			Document document = view.Document;
			double[] array = new double[2];
			PlanViewRange viewRange = (view as Autodesk.Revit.DB.ViewPlan).GetViewRange();
			ElementId levelId = viewRange.GetLevelId(0);
			double num = 30.0;
            ElementId levelId2 = viewRange.GetLevelId((PlanViewPlane)1);
			if (levelId2 != null && this.doc.GetElementById(levelId) != null && this.doc.GetElementById(levelId2) is Level)
			{
                num = (this.doc.GetElementById(levelId2) as Level).Elevation + viewRange.GetOffset((PlanViewPlane)1);
			}
			double elevation = (this.doc.GetElementById(levelId) as Level).Elevation;
			array[1] = elevation + num;
            ElementId levelId3 = viewRange.GetLevelId((PlanViewPlane)2);
			if (levelId3.IntegerValue <= 0)
			{
				array[0] = elevation;
			}
			else
			{
                double offset = viewRange.GetOffset((PlanViewPlane)2);
				double elevation2 = (this.doc.GetElementById(levelId3) as Level).Elevation;
				array[0] = elevation2 + offset;
			}
			return array;
		}

		private Outline CreatOutLine(double[] viewRanges, XYZ point1, XYZ point2)
		{
			XYZ[] array = this.ReCombinPoints(point1, point2);
			XYZ xyz = new XYZ(array[0].X, array[0].Y, viewRanges[0]);
			XYZ xyz2 = new XYZ(array[1].X, array[1].Y, viewRanges[1]);
			return new Outline(xyz, xyz2);
		}

		private XYZ[] ReCombinPoints(XYZ point1, XYZ point2)
		{
			XYZ[] array = new XYZ[2];
			double x;
			double x2;
			if (point1.X > point2.X)
			{
				x = point2.X;
				x2 = point1.X;
			}
			else
			{
				x2 = point2.X;
				x = point1.X;
			}
			double y;
			double y2;
			if (point1.Y > point2.Y)
			{
				y = point2.Y;
				y2 = point1.Y;
			}
			else
			{
				y2 = point2.Y;
				y = point1.Y;
			}
			array[0] = new XYZ(x, y, 0.0);
			array[1] = new XYZ(x2, y2, 0.0);
			return array;
		}

		public bool ExtendAndMovePickedElements(XYZ vector)
		{
			if (vector == null)
			{
				return false;
			}
			bool flag = this.ExtendIntersectBoxElements(vector);
			this.MoveOrExtendGroupElements(vector);
			bool flag2 = this.MoveInSideBoxElements(vector);
			this.MoveOrExtendFilledRegionElements(vector);
			if (!flag2 && !flag)
			{
				return false;
			}
			this.doc.Regenerate();
			return true;
		}

		private bool MoveOrExtendGroupElements(XYZ vector)
		{
			foreach (Group g in this.groupList)
			{
				bool flag = this.MoveOrExtendGroup(g, vector);
				if (!flag)
				{
					return flag;
				}
			}
			return true;
		}

		private string GetTypeName(Group g)
		{
			IDictionary<string, string> markInfoFromElement = AssociationMarkInfo.GetMarkInfoFromElement(g);
			if (markInfoFromElement == null)
			{
				return null;
			}
			return markInfoFromElement.FirstOrDefault((KeyValuePair<string, string> q) => q.Key == "typeName").Value;
		}

		private bool MoveOrExtendGroup(Group g, XYZ vector)
		{
			string typeName = this.GetTypeName(g);
			ElementSet elementSet = new ElementSet();
			foreach (ElementId elementId in g.UngroupMembers())
			{
				if (!(elementId == null))
				{
					Element elementById = this.doc.GetElementById(elementId);
					if (elementById != null)
					{
						elementSet.Insert(elementById);
						Location location = elementById.Location;
						if (location is LocationCurve)
						{
							Curve curve = (location as LocationCurve).Curve;
							if (this.IsCrossWithBox(this.pickedBox, curve))
							{
								if (!(curve is Line))
								{
									location.Move(vector);
								}
								else
								{
									XYZ xyz = curve.GetEndPoint(0);
									XYZ xyz2 = curve.GetEndPoint(1);
									if (!this.JudgeVectorBeParral(YJKRevitTools.SetZToZero(xyz), YJKRevitTools.SetZToZero(xyz2), vector))
									{
										location.Move(vector);
									}
									else
									{
										if (this.IsInBox(this.pickedBox, xyz))
										{
											xyz += vector;
										}
										if (this.IsInBox(this.pickedBox, xyz2))
										{
											xyz2 += vector;
										}
										YJKLine hyline = new YJKLine(xyz, xyz2);
										(location as LocationCurve).Curve = hyline.Line;
									}
								}
							}
						}
						else
						{
							location.Move(vector);
						}
					}
				}
			}
			this.doc.Regenerate();
			if (elementSet.Size > 1)
			{
				Group group = this.doc.CreatYJKGroup(elementSet);
				if (group != null && !string.IsNullOrEmpty(typeName))
				{
					AssociationMarkInfo.GetMarkInfoFromElement(group);
				}
			}
			return true;
		}

		private bool MoveOrExtendFilledRegionElements(XYZ vector)
		{
			foreach (FilledRegion filledRegion in this.FilledRegions)
			{
				bool flag = this.MoveOrExtendFilledRegionElement(filledRegion, vector);
				if (!flag)
				{
					return flag;
				}
			}
			return true;
		}

		private bool MoveOrExtendFilledRegionElement(FilledRegion filledRegion, XYZ vector)
		{
			int num = this.ExtrudeType(this.pickedBox, filledRegion);
			List<Element> list = new List<Element>();
			list.Add(filledRegion);
			if (num == 0)
			{
				this.hyRotate.MoveElements(vector, list);
				return true;
			}
			if (num == 1)
			{
				return true;
			}
			IEnumerable<CurveLoop> boundaries = filledRegion.GetBoundaries();
			List<CurveLoop> list2 = new List<CurveLoop>();
			foreach (CurveLoop curveLoop in boundaries)
			{
				CurveLoopIterator curveLoopIterator = curveLoop.GetCurveLoopIterator();
				List<Curve> list3 = new List<Curve>();
				List<Curve> list4 = new List<Curve>();
				while (curveLoopIterator.MoveNext())
				{
					Curve curve = curveLoopIterator.Current;
					Curve item = curve.Clone();
					if (curve is Line && this.BeHaveIntersectPoint(curve as Line))
					{
						XYZ xyz = curve.GetEndPoint(0);
						XYZ xyz2 = curve.GetEndPoint(1);
						if (!this.IsInBox(this.pickedBox, xyz) && !this.IsInBox(this.pickedBox, xyz2))
						{
							Line line = this.GetLineFromPoint(filledRegion, xyz, vector, ref list4, curve as Line);
							if (line == null)
							{
								line = this.CreateLine(xyz, xyz + vector);
							}
							list3.Add(line);
							Line line2 = this.GetLineFromPoint(filledRegion, xyz2, vector, ref list4, curve as Line);
							if (line2 == null)
							{
								line2 = this.CreateLine(xyz2 + vector, xyz2);
							}
							list3.Add(line2);
							item = this.CreateLine(xyz + vector, xyz2 + vector);
						}
						else
						{
							if (this.IsInBox(this.pickedBox, xyz))
							{
								xyz += vector;
							}
							if (this.IsInBox(this.pickedBox, xyz2))
							{
								xyz2 += vector;
							}
							item = this.CreateLine(xyz, xyz2);
						}
					}
					else if (curve is Arc && this.IsCrossWithBox(this.pickedBox, curve))
					{
						XYZ xyz3 = curve.Tessellate()[0];
						XYZ xyz4 = curve.Tessellate()[curve.Tessellate().Count - 1];
						XYZ xyz5 = new XYZ(xyz3.X, xyz3.Y, xyz3.Z);
						XYZ xyz6 = new XYZ(xyz4.X, xyz4.Y, xyz4.Z);
						xyz3 += vector;
						if (!this.IsInBox(this.pickedBox, xyz5))
						{
							Line line3 = this.GetLineFromPoint(filledRegion, xyz5, vector, ref list4, null);
							if (line3 == null)
							{
								line3 = this.CreateLine(xyz5, xyz3);
							}
							list3.Add(line3);
						}
						xyz4 += vector;
						if (!this.IsInBox(this.pickedBox, xyz6))
						{
							Line line4 = this.GetLineFromPoint(filledRegion, xyz6, vector, ref list4, null);
							if (line4 == null)
							{
								line4 = this.CreateLine(xyz4, xyz6);
							}
							list3.Add(line4);
						}
						item = this.doc.CreatYJKArc(xyz3, xyz4, curve.Tessellate()[int.Parse((curve.Tessellate().Count / 2).ToString())] + vector);
					}
					list3.Add(item);
				}
				for (int i = list3.Count - 1; i >= 0; i--)
				{
					Curve curve2 = list3[i];
					if (curve2 == null)
					{
						list3.RemoveAt(i);
					}
					else if (list3[i] is Line)
					{
						foreach (Curve curve3 in list4)
						{
							curve2.GetEndPoint(0);
							curve2.GetEndPoint(1);
							if ((curve2.GetEndPoint(0).IsAlmostEqualTo(curve3.GetEndPoint(0)) && curve2.GetEndPoint(1).IsAlmostEqualTo(curve3.GetEndPoint(1))) || (curve2.GetEndPoint(0).IsAlmostEqualTo(curve3.GetEndPoint(1)) && curve2.GetEndPoint(1).IsAlmostEqualTo(curve3.GetEndPoint(0))))
							{
								list3.RemoveAt(i);
								break;
							}
						}
					}
				}
				this.SortCurveList(ref list3);
				CurveLoop curveLoop2 = new CurveLoop();
				foreach (Curve curve4 in list3)
				{
					curveLoop2.Append(curve4);
				}
				list2.Add(curveLoop2);
			}
			FilledRegion.Create(this.doc, filledRegion.GetTypeId(), this.doc.ActiveView.Id, list2);
			this.doc.DeleteElement(filledRegion);
			return true;
		}

		private Line CreateLine(XYZ sP, XYZ eP)
		{
			if (sP.IsAlmostEqualTo(eP))
			{
				return null;
			}
			return Line.CreateBound(sP, eP);
		}

		private bool BeHaveIntersectPoint(Line line)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			if (YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint), this.boundingBoxPoints) || YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint2), this.boundingBoxPoints))
			{
				return true;
			}
			YJKLine hyline = new YJKLine(this.boundingBoxPoints[0], this.boundingBoxPoints[1]);
			YJKLine hyline2 = new YJKLine(this.boundingBoxPoints[1], this.boundingBoxPoints[2]);
			YJKLine hyline3 = new YJKLine(this.boundingBoxPoints[2], this.boundingBoxPoints[3]);
			YJKLine hyline4 = new YJKLine(this.boundingBoxPoints[3], this.boundingBoxPoints[0]);
			return hyline.IntersectionPoint(line) != null || hyline2.IntersectionPoint(line) != null || hyline3.IntersectionPoint(line) != null || hyline4.IntersectionPoint(line) != null;
		}

		private Line GetLineFromPoint(FilledRegion filReg, XYZ point, XYZ dDir, ref List<Curve> curOutList, Line lSelf = null)
		{
			foreach (CurveLoop curveLoop in filReg.GetBoundaries())
			{
				CurveLoopIterator curveLoopIterator = curveLoop.GetCurveLoopIterator();
				while (curveLoopIterator.MoveNext())
				{
					Curve curve = curveLoopIterator.Current;
					if (curve is Line)
					{
						XYZ endPoint = curve.GetEndPoint(0);
						XYZ endPoint2 = curve.GetEndPoint(1);
						if (!(lSelf != null) || ((!lSelf.GetEndPoint(0).IsAlmostEqualTo(endPoint) || !lSelf.GetEndPoint(1).IsAlmostEqualTo(endPoint2)) && (!lSelf.GetEndPoint(0).IsAlmostEqualTo(endPoint2) || !lSelf.GetEndPoint(1).IsAlmostEqualTo(endPoint))))
						{
							if (point.IsAlmostEqualTo(endPoint))
							{
								curOutList.Add(curve);
								return this.CreateLine(endPoint + dDir, endPoint2);
							}
							if (point.IsAlmostEqualTo(endPoint2))
							{
								curOutList.Add(curve);
								return this.CreateLine(endPoint, endPoint2 + dDir);
							}
						}
					}
				}
			}
			return null;
		}

		private void SortCurveList(ref List<Curve> curFromList)
		{
			if (curFromList == null || curFromList.Count <= 0)
			{
				return;
			}
			List<Curve> list = new List<Curve>();
			Curve curve = curFromList[0];
			list.Add(curve);
			curFromList.RemoveAt(0);
			XYZ xyz = curve.Tessellate()[curve.Tessellate().Count - 1];
			this.SortFromConnectTo(curve.GetEndPoint(0), ref xyz, curFromList, list);
			curFromList = list;
		}

		private void SortFromConnectTo(XYZ pointOrder, ref XYZ pointTo, List<Curve> curFromList, List<Curve> curToList)
		{
			if (curFromList == null || curFromList.Count <= 0 || curToList == null || pointOrder.IsAlmostEqualTo(pointTo))
			{
				return;
			}
			for (int i = 0; i < curFromList.Count; i++)
			{
				if (curFromList[i].GetEndPoint(0).IsAlmostEqualTo(pointTo))
				{
					pointTo = curFromList[i].Tessellate()[curFromList[i].Tessellate().Count - 1];
					curToList.Add(curFromList[i]);
					curFromList.RemoveAt(i);
					this.SortFromConnectTo(pointOrder, ref pointTo, curFromList, curToList);
					return;
				}
			}
		}

		private bool IsCrossWithBox(PickedBox box, Curve ve)
		{
			foreach (XYZ point in ve.Tessellate())
			{
				if (this.IsInBox(box, point))
				{
					return true;
				}
			}
			return false;
		}

		private int ExtrudeType(PickedBox box, FilledRegion filReg)
		{
			IList<CurveLoop> boundaries = filReg.GetBoundaries();
			bool flag = true;
			foreach (CurveLoop curveLoop in boundaries)
			{
				CurveLoopIterator curveLoopIterator = curveLoop.GetCurveLoopIterator();
				while (curveLoopIterator.MoveNext())
				{
					Curve curve = curveLoopIterator.Current;
					foreach (XYZ point in curve.Tessellate())
					{
						if (!this.IsInBox(box, point))
						{
							flag = false;
							break;
						}
					}
					if (!flag)
					{
						break;
					}
				}
				if (!flag)
				{
					break;
				}
			}
			if (flag)
			{
				return 0;
			}
			foreach (CurveLoop curveLoop2 in boundaries)
			{
				CurveLoopIterator curveLoopIterator2 = curveLoop2.GetCurveLoopIterator();
				new CurveLoop();
				while (curveLoopIterator2.MoveNext())
				{
					Curve curve2 = curveLoopIterator2.Current;
					if (!(curve2 is Line) && !(curve2 is Arc))
					{
						foreach (XYZ point2 in curve2.Tessellate())
						{
							if (this.IsInBox(box, point2))
							{
								return 1;
							}
						}
					}
				}
			}
			return 2;
		}

		private bool IsInBox(PickedBox box, XYZ point)
		{
			double x;
			double x2;
			if (box.Min.X > box.Max.X)
			{
				x = box.Min.X;
				x2 = box.Max.X;
			}
			else
			{
				x = box.Max.X;
				x2 = box.Min.X;
			}
			double y;
			double y2;
			if (box.Min.Y > box.Max.Y)
			{
				y = box.Min.Y;
				y2 = box.Max.Y;
			}
			else
			{
				y = box.Max.Y;
				y2 = box.Min.Y;
			}
			return point.X > x2 && point.X < x && point.Y > y2 && point.Y < y;
		}

		private bool MoveInSideBoxElements(XYZ vector)
		{
			if (this.InsideElemList == null || this.InsideElemList.Count < 1)
			{
				return false;
			}
			this.hyRotate.MoveElements(vector, this.InsideElemList);
			return true;
		}

		private bool ExtendIntersectBoxElements(XYZ vector)
		{
			if (this.IntersectElemList == null || this.IntersectElemList.Count < 1)
			{
				return false;
			}
			foreach (Element element in this.IntersectElemList)
			{
				if (element is Grid)
				{
					this.ExtendGrid(element as Grid, vector);
				}
				else if (element is Wall || element is CurveElement)
				{
					this.ExtendWallOrCurveElement(element, vector);
				}
				else
				{
					this.ExtendMepCurveElement(element, vector);
				}
			}
			return true;
		}

		private void ExtendMepCurveElement(Element elem, XYZ vector)
		{
			LocationCurve locationCurve = elem.Location as LocationCurve;
			if (locationCurve == null)
			{
				return;
			}
			Curve curve = locationCurve.Curve;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = hyendPoint.Subtract(hyendPoint2).Normalize();
			List<Connector> curveEndConnectors = YJKRevitTools.GetCurveEndConnectors(elem as MEPCurve);
			List<Connector> list = new List<Connector>();
			foreach (Connector connector in curveEndConnectors)
			{
				if (connector.CoordinateSystem.BasisZ.IsAlmostEqualTo(xyz, 0.0001) || connector.CoordinateSystem.BasisZ.IsAlmostEqualTo(-1.0 * xyz, 0.0001))
				{
					list.Add(connector);
				}
			}
			bool flag = this.JudgeVectorBeParral(YJKRevitTools.SetZToZero(hyendPoint), YJKRevitTools.SetZToZero(hyendPoint2), vector);
			new List<Element>().Add(elem);
			bool flag2 = this.BeInSideBoxConnector(list[0]);
			bool flag3 = this.BeInSideBoxConnector(list[1]);
			if ((flag2 && list[0].IsConnected) || (flag3 && list[1].IsConnected))
			{
				return;
			}
			if (!flag)
			{
				locationCurve.Move(vector);
				return;
			}
			if ((!flag2 && !list[0].IsConnected) || (!flag3 && !list[1].IsConnected))
			{
				YJKLine hyline;
				if (flag2)
				{
					hyline = new YJKLine(list[1].Origin, list[0].Origin.Add(vector));
				}
				else
				{
					hyline = new YJKLine(list[0].Origin, list[1].Origin.Add(vector));
				}
				locationCurve.Curve = hyline.Line;
				return;
			}
			locationCurve.Move(vector);
		}

		private bool BeInSideBoxConnector(Connector conn)
		{
			string str = "";
			foreach (XYZ xyz in this.boundingBoxPoints)
			{
				str = str + xyz.ToString() + "\n";
			}
			str = str + conn.Origin.ToString() + "\n";
			return YJKRevitTools.Contains(YJKRevitTools.SetZToZero(conn.Origin), this.boundingBoxPoints);
		}

		private void GetOrderConnectors(Curve curve, List<Connector> listConn, ref Connector inConn, ref Connector outConn)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			curve.GetEndPoint(1);
			if (listConn[0].Origin.IsAlmostEqualTo(hyendPoint, 0.001))
			{
				inConn = listConn[0];
				outConn = listConn[1];
				return;
			}
			inConn = listConn[1];
			outConn = listConn[0];
		}

		private void ExtendWallOrCurveElement(Element elem, XYZ vector)
		{
			LocationCurve locationCurve = elem.Location as LocationCurve;
			Curve curve = locationCurve.Curve;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			bool flag = YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint), this.boundingBoxPoints);
			bool flag2 = YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint2), this.boundingBoxPoints);
			bool locationCurveJoinedElements = this.GetLocationCurveJoinedElements(elem, 0);
			bool locationCurveJoinedElements2 = this.GetLocationCurveJoinedElements(elem, 1);
			bool flag3 = this.JudgeVectorBeParral(YJKRevitTools.SetZToZero(hyendPoint), YJKRevitTools.SetZToZero(hyendPoint2), vector);
			List<Element> list = new List<Element>();
			list.Add(elem);
			if (!flag3)
			{
				this.hyRotate.MoveElements(vector, list);
				return;
			}
			if ((!locationCurveJoinedElements && locationCurveJoinedElements2 && !flag2) || (locationCurveJoinedElements && !locationCurveJoinedElements2 && !flag))
			{
				this.hyRotate.MoveElements(vector, list);
				return;
			}
			if (!locationCurveJoinedElements2 && !locationCurveJoinedElements)
			{
				YJKLine hyline;
				if (flag)
				{
					hyline = new YJKLine(hyendPoint2, hyendPoint.Add(vector));
				}
				else
				{
					hyline = new YJKLine(hyendPoint, hyendPoint2.Add(vector));
				}
				locationCurve.Curve = hyline.Line;
			}
		}

		private bool JudgeVectorBeParral(XYZ startPnt, XYZ endPnt, XYZ baseVector)
		{
			baseVector = baseVector.Normalize();
			XYZ xyz = startPnt.Subtract(endPnt).Normalize();
			return xyz.IsAlmostEqualTo(baseVector, 0.001) || xyz.IsAlmostEqualTo(-1.0 * baseVector, 0.001);
		}

		private void ExtendGrid(Grid grid, XYZ vector)
		{
			Curve curve = grid.Curve;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			bool flag = YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint), this.boundingBoxPoints);
			bool flag2 = YJKRevitTools.Contains(YJKRevitTools.SetZToZero(hyendPoint2), this.boundingBoxPoints);
			List<Element> list = new List<Element>();
			list.Add(grid);
			if (flag && flag2)
			{
				this.hyRotate.MoveElements(vector, list);
				return;
			}
			hyendPoint.Subtract(hyendPoint2).Normalize();
			if (this.JudgeVectorBeParral(hyendPoint, hyendPoint2, vector))
			{
				YJKLine hyline;
				if (flag)
				{
					hyline = new YJKLine(hyendPoint2, hyendPoint.Add(vector));
				}
				else
				{
					hyline = new YJKLine(hyendPoint, hyendPoint2.Add(vector));
				}
				this.doc.DeleteElement(grid);
				GridType gridType = this.doc.YjkNewGrid(hyline.Line).GetGridType();
				gridType.GetParameter(BuiltInParameter.GRID_BUBBLE_END_1).Set(1);
				gridType.GetParameter(BuiltInParameter.GRID_BUBBLE_END_2).Set(1);
				return;
			}
			this.hyRotate.MoveElements(vector, list);
		}

		private bool GetBoundingBoxElements(Element elem)
		{
			View activeView = this.doc.ActiveView;
			BoundingBoxXYZ boundingBoxXYZ = elem.get_BoundingBox(activeView);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(new Outline(boundingBoxXYZ.Min, boundingBoxXYZ.Max));
			List<BuiltInCategory> list = new List<BuiltInCategory>();
            BuiltInCategory integerValue = (BuiltInCategory)elem.Category.Id.IntegerValue;
			list.Add(integerValue);
			ElementMulticategoryFilter elementMulticategoryFilter = new ElementMulticategoryFilter(list);
			ExclusionFilter exclusionFilter = new ExclusionFilter(new List<ElementId>
			{
				elem.Id
			});
			List<Element> list2 = new FilteredElementCollector(elem.Document).WherePasses(exclusionFilter).WherePasses(elementMulticategoryFilter).WherePasses(boundingBoxIntersectsFilter).ToList<Element>();
			return list2 != null && list2.Count >= 1;
		}

		private bool GetLocationCurveJoinedElements(Element elem, int index)
		{
			List<Element> list = new List<Element>();
			if (index < 0)
			{
				return true;
			}
			LocationCurve locationCurve = elem.Location as LocationCurve;
			if (locationCurve != null)
			{
				foreach (object obj in locationCurve.get_ElementsAtJoin(index))
				{
					Element element = (Element)obj;
					if (!(element.Id == elem.Id))
					{
						list.Add(element);
					}
				}
			}
			return list != null && list.Count >= 1;
		}

		private int JudgeNoSideBoxLocationEndPoint(Element elem, bool beInSide = false)
		{
			int result = -1;
			LocationCurve locationCurve = elem.Location as LocationCurve;
			if (locationCurve == null)
			{
				return result;
			}
			if (YJKRevitTools.Contains(YJKRevitTools.SetZToZero(locationCurve.Curve.GetEndPoint(0)), this.boundingBoxPoints))
			{
				if (beInSide)
				{
					result = 0;
				}
				else
				{
					result = 1;
				}
			}
			else if (beInSide)
			{
				result = 1;
			}
			else
			{
				result = 0;
			}
			return result;
		}

		private PickedBox pickedBox;

		private Document doc;

		private Selection sel;

		private List<Element> insideCurveElems = new List<Element>();

		private List<Element> insideFamilyInstances = new List<Element>();

		private List<XYZ> boundingBoxPoints;

		private YJKRotateFamilyInstance hyRotate = new YJKRotateFamilyInstance();

		private List<Element> intersectElemList = new List<Element>();

		private List<YJKLine> interectElemsLine = new List<YJKLine>();

		private List<YJKLine> insideElemsLine = new List<YJKLine>();

		private List<Element> insideElemList = new List<Element>();

		private List<Group> groupList = new List<Group>();

		private List<FilledRegion> filledRegions = new List<FilledRegion>();

		private string operateMsg;
	}
}
